/********************************************************************
# Copyright 2017 Daniel 'grindhold' Brendle
#
# This file is part of parceldude.
#
# parceldude is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either
# version 3 of the License, or (at your option) any later
# version.
#
# parceldude is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with parceldude.
# If not, see http://www.gnu.org/licenses/.
*********************************************************************/

namespace Parceldude {
    [GtkTemplate (ui = "/de/grindhold/parceldude/ui/installview.ui")]
    public class InstallView : Gtk.Box {
        private ConfigView config;
        [GtkChild]
        private Gtk.Label label;
        [GtkChild]
        private Gtk.ProgressBar progress;

        private const string LABELTEXT = "Installing %d/%d %s";

        private uint counter=0;
        private uint total=0;
        private string current_installer = "";

        public signal void done();

        public InstallView(ConfigView config) {
            this.config = config;
            this.show_all();
            this.total = config.get_installers().length();
            try {
                new Thread<int>.try("installer", this.run);
            } catch (Error e) {
                warning("Could not launch installer thread: %s", e.message);
            }
        }

        private void update_label() {
            uint c = 0;
            string installer;
            lock(this.counter) {
                c = this.counter;
            }
            lock(this.current_installer) {
                installer = this.current_installer;
            }
            this.label.label = LABELTEXT.printf(c, this.total, installer);
        }

        private void update_progress() {
            double c = 0;
            lock(this.counter) {
                c = (double)this.counter;
            }
            this.progress.fraction = c / (double)this.total ;
        }

        private int run() {
            foreach (Installer installer in this.config.get_installers()) {
                string filepath = installer.filepath;
                string output;
                string file = GLib.Path.get_basename(filepath);
                string folder = GLib.Path.get_dirname(filepath);
                string featurelist = installer.get_paramstring();
                lock (this.current_installer) {
                    this.current_installer = file;
                }
                lock(this.counter) {
                    this.counter++;
                }

                Idle.add(()=>{
                    this.update_label();
                    this.update_progress();
                    return false;
                });

                string[] parameters;
                if (featurelist != null && featurelist != "") {
                    parameters = {"msiexec","/i",file,"/quiet", "ADDLOCAL="+featurelist};
                } else {
                    parameters = {"msiexec","/i",file,"/quiet"};
                }

                try {
                    GLib.Process.spawn_sync(folder, parameters, Environ.get(), SpawnFlags.SEARCH_PATH, null, null, out output, null);
                } catch (SpawnError e) {
                    message ("Could not launch msiexec: %s", e.message);
                }
            }
            Idle.add(()=>{
                this.done();
                return false;
            });
            return 0;
        }
    }
}
